package texture;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.JsonObject;

public class MetadataSerializer {
	private final IRegistry<String, MetadataSerializerRegistration> registry = new RegistrySimple<>();
	private final GsonBuilder gsonBuilder = new GsonBuilder();
	private Gson gson;

	public void registerMetadataSectionType(MetadataSectionSerializer<? extends MetadataSection> serializer, Class<? extends MetadataSection> clazz) {
		this.registry.putObject(serializer.getSectionName(), new MetadataSerializerRegistration(this, serializer, clazz));
		this.gsonBuilder.registerTypeAdapter(clazz, serializer);
		this.gson = null;
	}

	public MetadataSection parseMetadataSection(String sectionName, JsonObject jsonObject) {
		if (sectionName == null) {
			throw new IllegalArgumentException("Metadata section name cannot be null");
		} else if (!jsonObject.has(sectionName)) {
			return null;
		} else if (!jsonObject.get(sectionName).isJsonObject()) {
			throw new IllegalArgumentException("Invalid metadata for \'" + sectionName + "\' - expected object, found " + jsonObject.get(sectionName));
		}

		MetadataSerializerRegistration metadataserializerregistration = this.registry.getObject(sectionName);

		if (metadataserializerregistration == null) {
			throw new IllegalArgumentException("Don\'t know how to handle metadata section \'" + sectionName + "\'");
		} else {
			return (MetadataSection) this.getGson().fromJson(jsonObject.getAsJsonObject(sectionName), metadataserializerregistration.getClazz());
		}
	}

	private Gson getGson() {
		if (this.gson == null) {
			this.gson = this.gsonBuilder.create();
		}

		return this.gson;
	}
}
